package crp.services.api.graphql.loaders;

import com.qwlabs.jackson.Jackson;
import com.qwlabs.lang.C2;
import crp.core.workflow.domain.services.WorkflowTaskSearcher;
import crp.services.api.graphql.models.WorkflowInstancePayload;
import crp.services.api.graphql.models.WorkflowTaskContextPayload;
import crp.services.api.graphql.models.WorkflowTaskPayload;
import org.eclipse.microprofile.graphql.GraphQLApi;
import org.eclipse.microprofile.graphql.Source;

import javax.enterprise.context.RequestScoped;
import javax.inject.Inject;
import javax.validation.constraints.NotNull;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.function.Function;
import java.util.stream.Stream;

@GraphQLApi
@RequestScoped
public class WorkflowTaskPayloadLoader {
    private final WorkflowTaskSearcher workflowTaskSearcher;
    private final WorkflowInstanceFetcher workflowInstanceFetcher;

    @Inject
    public WorkflowTaskPayloadLoader(WorkflowTaskSearcher workflowTaskSearcher,
                                     WorkflowInstanceFetcher workflowInstanceFetcher) {
        this.workflowTaskSearcher = workflowTaskSearcher;
        this.workflowInstanceFetcher = workflowInstanceFetcher;
    }

    public List<@NotNull WorkflowTaskContextPayload> context(@Source List<WorkflowTaskPayload> workflowTaskPayloads) {
        Set<String> ids = C2.set(workflowTaskPayloads, WorkflowTaskPayload::getId);
        Stream<WorkflowTaskContextPayload> context = workflowTaskSearcher.byIds(ids)
                .map(item -> WorkflowTaskContextPayload.builder().autocomplete(item.getContext().isAutocomplete())
                        .comment(item.getContext().getComment())
                        .nodeId(item.getContext().getNodeId())
                        .topic(item.getContext().getTopic())
                        .formAttributes(Jackson.write(item.getContext().getFormAttributes()).orElse("")).build());
        return C2.list(context);

    }

    public List<@NotNull WorkflowInstancePayload> instance(@Source List<WorkflowTaskPayload> workflowTaskPayloads) {
        Set<String> ids = C2.set(workflowTaskPayloads, WorkflowTaskPayload::getInstanceId);
        Map<String, WorkflowInstancePayload> instanceMap = C2.map(workflowInstanceFetcher.fetch(ids),
                WorkflowInstancePayload::getId, Function.identity());
        return C2.list(workflowTaskPayloads,
                item -> instanceMap.get(item.getInstanceId()));

    }
}
